import UIKit
import HyphenateChat

//MARK: - DispatchQueue
fileprivate extension DispatchQueue {
    private static var _onceToken = [String]()
    
    class func ballChat_once(token: String = "\(#file):\(#function):\(#line)", block: ()->Void) {
        objc_sync_enter(self)
        defer {
            objc_sync_exit(self)
        }
        if _onceToken.contains(token) {
            return
        }
        _onceToken.append(token)
        block()
    }
}

// 禁止被继承
final class PixelWorldChatManager: NSObject, PixelWorldChatProtocol {
    
    static let share = PixelWorldChatManager()
    /// 登录、注册最大重试次数（默认两次）
    var maxRetryCount: Int = 2
    /// 用户通用密码
    let defaultPassword: String = "Ajk043sQ1GiM5W"
    /// 用户唯一标识保存Key
    private let ballChat_UserIdentifiesKey = "BALLUSERIDENTIFIESKEY"
    /// 当前会话(获取最新消息时保存)
    private var ballChat_Conversation: EMConversation?
    /// 是否过滤环信官方消息
    var ballChat_filterHuanXinChat: Bool = true
    /// 保存所有需要接收消息的block
    var ballChat_allMesssageBlocks: [String: PixelWorldChatStatusBlock?] = [:]
    
    //TODO: - 配置环信
    /// 配置环信
    func configChat(appKey: String) {
        // 防止多次调用
        DispatchQueue.ballChat_once {
            let options = EMOptions(appkey: appKey)
            // 离开聊天室时是否删除所有消息
            options?.deleteMessagesOnLeaveChatroom = false
            // 是否自动同意好友邀请
            options?.autoAcceptFriendInvitation = true
            // 是否自动登录
            options?.isAutoLogin = true
            // 初始化
            PixelWorldChatEMClient.initializeSDK(with: options)
            /// 登录状态提示
            PixelWorldChatEMClient.add(self, delegateQueue: DispatchQueue.global())
            /// 接收新消息提示（如果崩溃在此处, 及有可能是未配置正确的appKey)
            PixelWorldChatEMClient.chatManager?.add(self, delegateQueue: DispatchQueue.global())
            /// 群成员变动通知
            PixelWorldChatEMClient.groupManager.add(self, delegateQueue: DispatchQueue.global())
            
            NotificationCenter.default.addObserver(forName: NSNotification.Name("SAYWAKE_SENDMESSAGENOTIFICATION"), object: nil, queue: nil) {[weak self] noti in
                self?.responseActions(noti)
            }
        }
    }
    
    private func responseActions(_ noti: Notification) {
        /**
         let object = ["type": SayWakeChatBlockPrefix.allError, "result": SayWakeChatStatusResult.failed(error.sayWakeError)] as [String : Any]
         NotificationCenter.default.post(name: NSNotification.Name("SAYWAKE_SENDMESSAGENOTIFICATION"), object: object)
         */
        guard let object = noti.object as? [String: Any], let blockType = object["type"] as? PixelWorldChatBlockPrefix else { return }
        if let result = object["result"] as? PixelWorldChatStatusResult {
            self.chat.responseAction(blockType, result: result)
        } else {
            self.chat.responseAction(blockType)
        }
    }
    
}

//MARK: - EMChatManagerDelegate
extension PixelWorldChatManager: EMChatManagerDelegate {
    
    //TODO: - 会话列表发生变化通知
    /// 会话列表发生变化通知

    func conversationListDidUpdate(_ aConversationList: [Any]!) {
        let models = self.chat.PixelWorldChat_analysisMessages(aConversationList)
        self.chat.responseAction(.conversation, result: .messages(models))
    }
    
    //TODO: - 收到新消息通知(普通)
    /// 收到新消息通知(普通)
    func messagesDidReceive(_ aMessages: [Any]!) {
        let models = self.chat.PixelWorldChat_analysisMessages(aMessages)
        let chatMessages = models.filter({ $0.messageType == .chat })
        /// 保存消息（只保存单聊消息）
        ChatCache.saveMessages(chatMessages, unReadCount: models.count)
        /// 返回消息
        self.chat.responseAction(.newMessage, result: .messages(models))
        // 通知会话列表刷新数据
        self.chat.responseAction(.conversation)
        // 刷新未读消息数量
        self.chat.responseAction(.unreadCount)
    }
    
    //TODO: - 收到CMD消息通知(CMD)
    /// 收到CMD消息通知(CMD)
    func cmdMessagesDidReceive(_ aCmdMessages: [Any]!) {
        let models = self.chat.PixelWorldChat_analysisMessages(aCmdMessages)
        self.chat.responseAction(.cmdMessage, result: .messages(models))
    }
    
}

//MARK: - EMGroupManagerDelegate
extension PixelWorldChatManager: EMGroupManagerDelegate {
    
    //TODO: - 有新成员加入群聊
    func userDidJoin(_ aGroup: EMGroup!, user aUsername: String!) {
        chat.responseAction(.groupMemberChange, result: .success(aGroup.groupId))
    }
    
    //TODO: - 有成员离开群聊
    func userDidLeave(_ aGroup: EMGroup!, user aUsername: String!) {
        chat.responseAction(.groupMemberChange, result: .success(aGroup.groupId))
    }
    
}

//MARK: - EMClientDelegate
extension PixelWorldChatManager: EMClientDelegate {
    /// 自动登录
    func autoLoginDidCompleteWithError(_ aError: EMError?) {
        if let error = aError {
            self.chat.responseAction(.autoLogin, result: .failed(error.PixelWorldChatError))
        } else {
            self.chat.responseAction(.autoLogin)
        }
    }
}

